home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / nfs / amd / amd-5.2 / amq / amq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-23  |  11.5 KB  |  533 lines

  1. /*
  2.  * $Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $
  3.  *
  4.  * Copyright (c) 1990 Jan-Simon Pendry
  5.  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  6.  * Copyright (c) 1990 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * This code is derived from software contributed to Berkeley by
  10.  * Jan-Simon Pendry at Imperial College, London.
  11.  *
  12.  * Redistribution and use in source and binary forms are permitted provided
  13.  * that: (1) source distributions retain this entire copyright notice and
  14.  * comment, and (2) distributions including binaries display the following
  15.  * acknowledgement:  ``This product includes software developed by the
  16.  * University of California, Berkeley and its contributors'' in the
  17.  * documentation or other materials provided with the distribution and in
  18.  * all advertising materials mentioning features or use of this software.
  19.  * Neither the name of the University nor the names of its contributors may
  20.  * be used to endorse or promote products derived from this software without
  21.  * specific prior written permission.
  22.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  23.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  24.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25.  */
  26.  
  27. /*
  28.  * Automounter query tool
  29.  */
  30.  
  31. #ifndef lint
  32. char copyright[] = "\
  33. @(#)Copyright (c) 1990 Jan-Simon Pendry\n\
  34. @(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
  35. @(#)Copyright (c) 1990 The Regents of the University of California.\n\
  36. @(#)All rights reserved.\n";
  37. #endif /* not lint */
  38.  
  39. #ifndef lint
  40. static char rcsid[] = "$Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $";
  41. static char sccsid[] = "%W% (Berkeley) %G%";
  42. #endif /* not lint */
  43.  
  44. #include "am.h"
  45. #include "amq.h"
  46. #include <stdio.h>
  47. #include <fcntl.h>
  48. #include <netdb.h>
  49.  
  50. char *progname;
  51. static int flush_flag;
  52. static int minfo_flag;
  53. static int unmount_flag;
  54. static int stats_flag;
  55. static char *debug_opts;
  56. static char *logfile;
  57. static char *xlog_opt;
  58. static char localhost[] = "localhost";
  59. static char *def_server = localhost;
  60.  
  61. extern int optind;
  62. extern char *optarg;
  63.  
  64. static struct timeval tmo = { 10, 0 };
  65. #define    TIMEOUT tmo
  66.  
  67. enum show_opt { Full, Stats, Calc, Short, ShowDone };
  68.  
  69. /*
  70.  * If (e) is Calc then just calculate the sizes
  71.  * Otherwise display the mount node on stdout
  72.  */
  73. static void show_mti(mt, e, mwid, dwid, twid)
  74. amq_mount_tree *mt;
  75. enum show_opt e;
  76. int *mwid;
  77. int *dwid;
  78. int *twid;
  79. {
  80.     switch (e) {
  81.     case Calc: {
  82.         int mw = strlen(mt->mt_mountinfo);
  83.         int dw = strlen(mt->mt_directory);
  84.         int tw = strlen(mt->mt_type);
  85.         if (mw > *mwid) *mwid = mw;
  86.         if (dw > *dwid) *dwid = dw;
  87.         if (tw > *twid) *twid = tw;
  88.     } break;
  89.  
  90.     case Full: {
  91.         struct tm *tp = localtime(&mt->mt_mounttime);
  92. printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
  93.             *dwid, *dwid,
  94.             *mt->mt_directory ? mt->mt_directory : "/",    /* XXX */
  95.             *twid, *twid,
  96.             mt->mt_type,
  97.             *mwid, *mwid, 
  98.             mt->mt_mountinfo,
  99.             mt->mt_mountpoint,
  100.  
  101.             mt->mt_mountuid,
  102.             mt->mt_getattr,
  103.             mt->mt_lookup,
  104.             mt->mt_readdir,
  105.             mt->mt_readlink,
  106.             mt->mt_statfs,
  107.  
  108.             tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
  109.             tp->tm_mon+1, tp->tm_mday,
  110.             tp->tm_hour, tp->tm_min, tp->tm_sec);
  111.     } break;
  112.  
  113.     case Stats: {
  114.         struct tm *tp = localtime(&mt->mt_mounttime);
  115. printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
  116.             *dwid, *dwid,
  117.             *mt->mt_directory ? mt->mt_directory : "/",    /* XXX */
  118.  
  119.             mt->mt_mountuid,
  120.             mt->mt_getattr,
  121.             mt->mt_lookup,
  122.             mt->mt_readdir,
  123.             mt->mt_readlink,
  124.             mt->mt_statfs,
  125.  
  126.             tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
  127.             tp->tm_mon+1, tp->tm_mday,
  128.             tp->tm_hour, tp->tm_min, tp->tm_sec);
  129.     } break;
  130.  
  131.     case Short: {
  132.         printf("%-*.*s %-*.*s %-*.*s %s\n",
  133.             *dwid, *dwid,
  134.             *mt->mt_directory ? mt->mt_directory : "/",
  135.             *twid, *twid,
  136.             mt->mt_type,
  137.             *mwid, *mwid,
  138.             mt->mt_mountinfo,
  139.             mt->mt_mountpoint);
  140.     } break;
  141.     }
  142. }
  143.  
  144. /*
  145.  * Display a mount tree.
  146.  */
  147. static void show_mt(mt, e, mwid, dwid, pwid)
  148. amq_mount_tree *mt;
  149. enum show_opt e;
  150. int *mwid;
  151. int *dwid;
  152. int *pwid;
  153. {
  154.     while (mt) {
  155.         show_mti(mt, e, mwid, dwid, pwid);
  156.         show_mt(mt->mt_next, e, mwid, dwid, pwid);
  157.         mt = mt->mt_child;
  158.     }
  159. }
  160.  
  161. static void show_mi(ml, e, mwid, dwid, twid)
  162. amq_mount_info_list *ml;
  163. enum show_opt e;
  164. int *mwid;
  165. int *dwid;
  166. int *twid;
  167. {
  168.     int i;
  169.     switch (e) {
  170.     case Calc: {
  171.         for (i = 0; i < ml->amq_mount_info_list_len; i++) {
  172.             amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
  173.             int mw = strlen(mi->mi_mountinfo);
  174.             int dw = strlen(mi->mi_mountpt);
  175.             int tw = strlen(mi->mi_type);
  176.             if (mw > *mwid) *mwid = mw;
  177.             if (dw > *dwid) *dwid = dw;
  178.             if (tw > *twid) *twid = tw;
  179.         }
  180.     } break;
  181.  
  182.     case Full: {
  183.         for (i = 0; i < ml->amq_mount_info_list_len; i++) {
  184.             amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
  185.             printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
  186.                         *mwid, *mwid, mi->mi_mountinfo,
  187.                         *dwid, *dwid, mi->mi_mountpt,
  188.                         *twid, *twid, mi->mi_type,
  189.                         mi->mi_refc, mi->mi_fserver,
  190.                         mi->mi_up > 0 ? "up" :
  191.                         mi->mi_up < 0 ? "starting" : "down");
  192.             if (mi->mi_error > 0) {
  193.                 extern char *sys_errlist[];
  194.                 extern int sys_nerr;
  195.                 if (mi->mi_error < sys_nerr)
  196.                     printf(" (%s)", sys_errlist[mi->mi_error]);
  197.                 else
  198.                     printf(" (Error %d)", mi->mi_error);
  199.             } else if (mi->mi_error < 0) {
  200.                 fputs(" (in progress)", stdout);
  201.             }
  202.             fputc('\n', stdout);
  203.         }
  204.     } break;
  205.     }
  206. }
  207.  
  208. /*
  209.  * Display general mount statistics
  210.  */
  211. static void show_ms(ms)
  212. amq_mount_stats *ms;
  213. {
  214.     printf("\
  215. requests  stale     mount     mount     unmount\n\
  216. deferred  fhandles  ok        failed    failed\n\
  217. %-9d %-9d %-9d %-9d %-9d\n",
  218.     ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
  219. }
  220.  
  221. static bool_t
  222. xdr_pri_free(xdr_args, args_ptr)
  223. xdrproc_t xdr_args;
  224. caddr_t args_ptr;
  225. {
  226.     XDR xdr;
  227.     xdr.x_op = XDR_FREE;
  228.     return ((*xdr_args)(&xdr, args_ptr));
  229. }
  230.  
  231. #ifdef hpux
  232. #include <cluster.h>
  233. static char *cluster_server()
  234. {
  235.     struct cct_entry *cp;
  236.  
  237.     if (cnodeid() == 0) {
  238.         /*
  239.          * Not clustered
  240.          */
  241.         return def_server;
  242.     }
  243.  
  244.     while (cp = getccent())
  245.         if (cp->cnode_type == 'r')
  246.             return cp->cnode_name;
  247.  
  248.  
  249.     return def_server;
  250. }
  251. #endif /* hpux */
  252.  
  253. /*
  254.  * MAIN
  255.  */
  256. main(argc, argv)
  257. int argc;
  258. char *argv[];
  259. {
  260.     int opt_ch;
  261.     int errs = 0;
  262.     char *server;
  263.     struct sockaddr_in server_addr;
  264.     int s = RPC_ANYSOCK;
  265.     CLIENT *clnt;
  266.     struct hostent *hp;
  267.     int nodefault = 0;
  268.  
  269.     /*
  270.      * Compute program name
  271.      */
  272.     if (argv[0]) {
  273.         progname = strrchr(argv[0], '/');
  274.         if (progname && progname[1])
  275.             progname++;
  276.         else
  277.             progname = argv[0];
  278.     }
  279.     if (!progname)
  280.         progname = "amq";
  281.  
  282.     /*
  283.      * Parse arguments
  284.      */
  285.     while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF)
  286.     switch (opt_ch) {
  287.     case 'f':
  288.         flush_flag = 1;
  289.         break;
  290.  
  291.     case 'h':
  292.         def_server = optarg;
  293.         break;
  294.  
  295.     case 'l':
  296.         logfile = optarg;
  297.         nodefault = 1;
  298.         break;
  299.  
  300.     case 'm':
  301.         minfo_flag = 1;
  302.         nodefault = 1;
  303.         break;
  304.  
  305.     case 's':
  306.         stats_flag = 1;
  307.         break;
  308.  
  309.     case 'u':
  310.         unmount_flag = 1;
  311.         break;
  312.  
  313.     case 'x':
  314.         xlog_opt = optarg;
  315.         nodefault = 1;
  316.         break;
  317.  
  318.     case 'D':
  319.         debug_opts = optarg;
  320.         nodefault = 1;
  321.         break;
  322.  
  323.     default:
  324.         errs = 1;
  325.         break;
  326.     }
  327.  
  328.     if (errs) {
  329. show_usage:
  330.         fprintf(stderr, "\
  331. Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
  332. \t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname);
  333.         exit(1);
  334.     }
  335.  
  336. #ifdef hpux
  337.     /*
  338.      * Figure out root server of cluster
  339.      */
  340.     if (def_server == localhost)
  341.         server = cluster_server();
  342.     else
  343. #endif /* hpux */
  344.     server = def_server;
  345.  
  346.     /*
  347.      * Get address of server
  348.      */
  349.     if ((hp = gethostbyname(server)) == 0) {
  350.         fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
  351.         exit(1);
  352.     }
  353.     bzero(&server_addr, sizeof server_addr);
  354.     server_addr.sin_family = AF_INET;
  355.     server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
  356.  
  357.     /*
  358.      * Create RPC endpoint
  359.      */
  360.     clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
  361.     if (clnt == 0) {
  362.         fprintf(stderr, "%s: ", progname);
  363.         clnt_pcreateerror(server);
  364.         exit(1);
  365.     }
  366.  
  367.     /*
  368.      * Control debugging
  369.      */
  370.     if (debug_opts) {
  371.         int *rc;
  372.         amq_setopt opt;
  373.         opt.as_opt = AMOPT_DEBUG;
  374.         opt.as_str = debug_opts;
  375.         rc = amqproc_setopt_1(&opt, clnt);
  376.         if (rc && *rc < 0) {
  377.             fprintf(stderr, "%s: daemon not compiled for debug", progname);
  378.             errs = 1;
  379.         } else if (!rc || *rc > 0) {
  380.             fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
  381.             errs = 1;
  382.         }
  383.     }
  384.  
  385.     /*
  386.      * Control logging
  387.      */
  388.     if (xlog_opt) {
  389.         int *rc;
  390.         amq_setopt opt;
  391.         opt.as_opt = AMOPT_XLOG;
  392.         opt.as_str = xlog_opt;
  393.         rc = amqproc_setopt_1(&opt, clnt);
  394.         if (!rc || *rc) {
  395.             fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt);
  396.             errs = 1;
  397.         }
  398.     }
  399.  
  400.     /*
  401.      * Control log file
  402.      */
  403.     if (logfile) {
  404.         int *rc;
  405.         amq_setopt opt;
  406.         opt.as_opt = AMOPT_LOGFILE;
  407.         opt.as_str = logfile;
  408.         rc = amqproc_setopt_1(&opt, clnt);
  409.         if (!rc || *rc) {
  410.             fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);
  411.             errs = 1;
  412.         }
  413.     }
  414.  
  415.     /*
  416.      * Flush map cache
  417.      */
  418.     if (logfile) {
  419.         int *rc;
  420.         amq_setopt opt;
  421.         opt.as_opt = AMOPT_FLUSHMAPC;
  422.         opt.as_str = "";
  423.         rc = amqproc_setopt_1(&opt, clnt);
  424.         if (!rc || *rc) {
  425.             fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
  426.             errs = 1;
  427.         }
  428.     }
  429.  
  430.     /*
  431.      * Mount info
  432.      */
  433.     if (minfo_flag) {
  434.         int dummy;
  435.         amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
  436.         if (ml) {
  437.             int mwid = 0, dwid = 0, twid = 0;
  438.             show_mi(ml, Calc, &mwid, &dwid, &twid);
  439.             mwid++; dwid++; twid++;
  440.             show_mi(ml, Full, &mwid, &dwid, &twid);
  441.  
  442.         } else {
  443.             fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
  444.         }
  445.     }
  446.  
  447.     /*
  448.      * Apply required operation to all remaining arguments
  449.      */
  450.     if (optind < argc) {
  451.         do {
  452.             char *fs = argv[optind++];
  453.             if (unmount_flag) {
  454.                 /*
  455.                  * Unmount request
  456.                  */
  457.                 amqproc_umnt_1(&fs, clnt);
  458.             } else {
  459.                 /*
  460.                  * Stats request
  461.                  */
  462.                 amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
  463.                 if (mtp) {
  464.                     amq_mount_tree *mt = *mtp;
  465.                     if (mt) {
  466.                         int mwid = 0, dwid = 0, twid = 0;
  467.                         show_mt(mt, Calc, &mwid, &dwid, &twid);
  468.                         mwid++; dwid++, twid++;
  469. #ifdef notdef
  470.         printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n",
  471.         "Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@",
  472.               dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where");
  473.                         show_mt(mt, Full, &mwid, &dwid, &twid);
  474. #endif /* notdef */
  475.         printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
  476.             dwid, dwid, "What");
  477.                         show_mt(mt, Stats, &mwid, &dwid, &twid);
  478.                     } else {
  479.                         fprintf(stderr, "%s: %s not automounted\n", progname, fs);
  480.                     }
  481.                     xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);
  482.                 } else {
  483.                     fprintf(stderr, "%s: ", progname);
  484.                     clnt_perror(clnt, server);
  485.                     errs = 1;
  486.                 }
  487.             }
  488.         } while (optind < argc);
  489.     } else if (unmount_flag) {
  490.         goto show_usage;
  491.     } else if (stats_flag) {
  492.         amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
  493.         if (ms) {
  494.             show_ms(ms);
  495.         } else {
  496.             fprintf(stderr, "%s: ", progname);
  497.             clnt_perror(clnt, server);
  498.             errs = 1;
  499.         }
  500.     } else if (!nodefault) {
  501.         amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
  502.         if (mlp) {
  503.             enum show_opt e = Calc;
  504.             int mwid = 0, dwid = 0, pwid = 0;
  505.             while (e != ShowDone) {
  506.                 int i;
  507.                 for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
  508.                     show_mt(mlp->amq_mount_tree_list_val[i],
  509.                          e, &mwid, &dwid, &pwid);
  510.                 }
  511.                 mwid++; dwid++, pwid++;
  512.                 if (e == Calc) e = Short;
  513.                 else if (e == Short) e = ShowDone;
  514.             }
  515.         } else {
  516.             fprintf(stderr, "%s: ", progname);
  517.             clnt_perror(clnt, server);
  518.             errs = 1;
  519.         }
  520.     }
  521.  
  522.     exit(errs);
  523. }
  524.  
  525. #ifdef DEBUG
  526. xfree(f, l, p)
  527. char *f, *l;
  528. voidp p;
  529. {
  530.     free(p);
  531. }
  532. #endif /* DEBUG */
  533.